#!/usr/bin/env python3
"""
频率敏感性诊断脚本
用于分析SIMION模型对频率变化的敏感性
"""

import os
import sys
import re
import subprocess
import time
from openpyxl import load_workbook

# 添加项目根目录到Python路径
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parent_dir)

from store import params_store

def analyze_frequency_sensitivity():
    """分析频率敏感性"""
    print("=== SIMION 频率敏感性诊断 ===\n")
    
    # 获取参数
    simion_path = params_store.get('simion_path')
    iob_path = params_store.get('iob_path')
    lua_path = params_store.get('lua_path')
    excel_save_path = params_store.get('excel_save_path')
    
    if not all([simion_path, iob_path, lua_path]):
        print("错误：缺少必要的参数配置")
        return
    
    print(f"SIMION路径: {simion_path}")
    print(f"IOB路径: {iob_path}")
    print(f"Lua路径: {lua_path}")
    print(f"Excel保存路径: {excel_save_path}")
    print()
    
    # 测试频率范围
    test_frequencies = [1000000, 1010000, 1020000, 1030000, 1040000, 1050000]
    results = []
    
    for freq in test_frequencies:
        print(f"测试频率: {freq} Hz")
        
        # 更新Lua文件中的频率
        if update_lua_frequency(lua_path, freq):
            # 执行SIMION命令
            success, output = run_simion_test(simion_path, iob_path)
            
            if success:
                # 解析输出
                splats = parse_splat_data(output)
                results.append({
                    'frequency': freq,
                    'splat_count': len(splats),
                    'success': True
                })
                print(f"  成功: 解析到 {len(splats)} 个Splat数据")
            else:
                results.append({
                    'frequency': freq,
                    'splat_count': 0,
                    'success': False
                })
                print(f"  失败: SIMION命令执行失败")
        else:
            results.append({
                'frequency': freq,
                'splat_count': 0,
                'success': False
            })
            print(f"  失败: Lua文件更新失败")
        
        time.sleep(1)  # 避免过快执行
    
    # 分析结果
    print("\n=== 诊断结果 ===")
    successful_tests = [r for r in results if r['success']]
    failed_tests = [r for r in results if not r['success']]
    
    print(f"成功测试: {len(successful_tests)}/{len(results)}")
    print(f"失败测试: {len(failed_tests)}/{len(results)}")
    
    if successful_tests:
        splat_counts = [r['splat_count'] for r in successful_tests]
        print(f"Splat数据范围: {min(splat_counts)} - {max(splat_counts)}")
        print(f"平均Splat数量: {sum(splat_counts)/len(splat_counts):.1f}")
    
    if failed_tests:
        print("\n失败的频率:")
        for result in failed_tests:
            print(f"  {result['frequency']} Hz")

def update_lua_frequency(lua_path, frequency):
    """更新Lua文件中的频率参数"""
    try:
        with open(lua_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # 替换频率参数
        content = re.sub(r'_frequency\s*=\s*[\d.]+', f'_frequency = {frequency}', content)
        
        with open(lua_path, 'w', encoding='utf-8') as f:
            f.write(content)
        
        return True
    except Exception as e:
        print(f"更新Lua文件失败: {e}")
        return False

def run_simion_test(simion_path, iob_path):
    """运行SIMION测试命令"""
    try:
        cmd = [simion_path, '--nogui', 'fly', iob_path]
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            encoding='gbk',
            errors='replace',
            timeout=300  # 5分钟超时
        )
        
        output = result.stdout + result.stderr
        success = result.returncode == 0
        
        return success, output
    except subprocess.TimeoutExpired:
        return False, "命令执行超时"
    except Exception as e:
        return False, f"命令执行失败: {e}"

def parse_splat_data(output):
    """解析Splat数据"""
    splats = []
    
    # 查找Splat数据行
    splat_pattern = r'Splat\s+(\d+):\s+x=([-\d.]+),\s+y=([-\d.]+),\s+z=([-\d.]+),\s+mass=([-\d.]+)'
    
    for line in output.split('\n'):
        match = re.search(splat_pattern, line)
        if match:
            try:
                x = float(match.group(2))
                y = float(match.group(3))
                z = float(match.group(4))
                mass = float(match.group(5))
                splats.append((x, y, z, mass))
            except ValueError:
                continue
    
    return splats

if __name__ == "__main__":
    analyze_frequency_sensitivity()
